<?php

class bn_dal
{

    public $conn;
    protected static $instance;

    function __construct()
    {
        include_once ('info.php');
        $options = array(PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'");
        $this->conn = new PDO("mysql:host=" . host . ";dbname=" . db_name .";charset=UTF-8", user, pass, $options);
    }
    
    public static function getInstance()
    {
        if (!isset(self::$instance))
        {
            self::$instance = new self();
        }
        return self::$instance;
    }
/////////////////private
    private function arr2query($arr)
    {
        $arr = array_keys($arr);
        $query='';
        foreach ($arr as $itm)
        {
            $query .= "and $itm? ";
        }
        $query = ' where' . ltrim($query, 'and');
        return $query;
    }

    private function toarray($param)
    {
        if (is_array($param))
            return $param;
        else
            return explode(',', $param);
    }
////////////////end private
///////////////select
    public function select($query, $param = array())
    {
        $param = self::toarray($param);
        if (key($param) != '')
        {
            $query .= self::arr2query($param);
            $param = array_values($param);
        }
        
        return new fetchall($this->conn,$query,$param);
    }
  
    public function getrow($query, $param = array(), $fetch_style = pdo::FETCH_ASSOC)
    {
        $param = self::toarray($param);
        if (key($param) != '')
        {
            $query .= self::arr2query($param);
            $param = array_values($param);
        }
        $rows = $this->conn->prepare($query);
        $rows->execute($param);
        return new fetch($rows);
    }

    public function getvalue($query, $param = array())
    {
        $param = self::toarray($param);
        if (key($param) != '')
        {
            $query .= self::arr2query($param);
            $param = array_values($param);
        }

        $rows = $this->conn->prepare($query);
        $rows->execute($param);
        $row = $rows->fetch(pdo::FETCH_NUM);
        return $row[0];
    }
    
    public function rowcount($query, $param = array())
    {
        $param = self::toarray($param);
        if (key($param) != '')
        {
            $query .= self::arr2query($param);
            $param = array_values($param);
        }

        $rows = $this->conn->prepare($query);
        $rows->execute($param);
        return $rows->rowCount();
    }


    public function hasrow($query, $param = array())
    {
        if (self::rowcount($query,$param) > 0)
            return true;
        else
            return false;
    }
////////////////////////////////////////////////////////////////////////////////////////////////////////end select
////////////////////////////////////////////////////////////////////////////////////////////////////////query
    public function query($query, $param = array())
    {
        $param = self::toarray($param);
        $state = $this->conn->prepare($query);
        $state->execute($param);
        return $state->rowCount();
    }

    public function insert($table, $param)
    {
        $param = self::toarray($param);
        $cols = self::Select("select distinct COLUMN_NAME from information_schema.columns where TABLE_SCHEMA='".db_name."' AND table_name = '$table'and extra<>'auto_increment'")->fetch();
        if (!empty($cols))
        {
            $cl='';
            $q='';
            foreach ($cols as $col)
            {
                $cl .= $col['COLUMN_NAME'] . ",";
                $q .= "?,";
            }
            $cl = rtrim($cl, ',');
            $q = rtrim($q, ',');
            $query = "insert into $table($cl)values($q)";
            self::query($query, $param);
            return $this->conn->lastInsertId($table);
        }
        return 0;
    }

    public function update($table,$value=array(), $param = array())
    {
      /*  foreach($value as $key => $val) 
        {
            if (empty($val)) 
            unset($value[$key]);
        } */
        $up='';
        foreach (array_keys($value) as $itm)
        {
            $up .= "$itm=?,";
        }
        $up = rtrim($up, ',');
        $value = array_values($value);
        $value=array_merge($value,array_values($param));
        $up = "update $table set $up ".self::arr2query($param);
        return self::query($up, $value);
    }

    public function delete($table, $val, $col='id')
    {
        return self::query("delete from $table where $col=?", array($val));
    }
////////////////////////////////////////////////////////////////////////////////////////////functions
    public function escape($value)
    {
		return str_replace(array('\\','\''),array('\\\\','\\\''),$value);
    }

    public function setAttribute($attr, $val)
    {
        return $this->conn->setAttribute($attr, $val);
    }

    public function Tables($has_table = '')
    {
        if ($has_table == '')
            $rows = $this->conn->query('show tables');
        else
            $rows = $this->conn->query("show tables like '$has_table'");
        return $rows->fetchAll(pdo::FETCH_COLUMN,0);
    }

    public function Table_columns($table)
    {
        return self::Select("select * from information_schema.columns where table_name ='" .$table. "'")->fetch();
    }

    function __destruct()
    {
        unset($this->conn);
    }

}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////


   class fetch
   {
    private $rows;
    function __construct($rows)
    {
       $this->rows=$rows; 
    }
    
    public function fetch()
    {
      return $this->rows->fetch(pdo::FETCH_ASSOC);  
    }
    
     public function fetchNUM()
    {
      return $this->rows->fetch(pdo::FETCH_NUM);  
    }
    
    public function fetchOBJ()
    {
      return $this->rows->fetch(pdo::FETCH_OBJ);  
    }
    
    public function fetcFUNC($funcname)
    {
      return $this->rows->fetch(pdo::FETCH_FUNC, $funcname);  
    }
    
    public function fetchCOL($column=0)
    {
      return $this->rows->fetch(pdo::FETCH_COLUMN, $column);  
    }
    
    public function fetchCLASS($class)
    {
      return $this->rows->fetch(pdo::FETCH_CLASS, $class);  
    }
    
    public function fetchGROUP()
    {
      return $this->rows->fetch(pdo::FETCH_CLASS | pdo::FETCH_GROUP);  
    }
   }
   
/////////////////////////////////////////////////////////////////////////////////////

class fetchall
{
  private $conn;
  private $query;
  private $param;
  private $order='';
  private $limit='';
  private $groupby='';

  
  function __construct($conn,$query,$param)
  {
    $this->conn=$conn;
    $this->query=$query;
    $this->param=$param;
  } 
  
  public function orderby($order)
  {
    $this->order=" order by $order";
    return $this;
  } 
  
  public function limit($limit)
  {
    $this->limit=" limit $limit";
    return $this;
  }
  
  public function groupby($group)
  {
    $this->groupby=" GROUP BY $group";
    return $this;
  }
  
      public function fetch()
    {
        $rows = $this->conn->prepare($this->query.$this->groupby.$this->order.$this->limit);
        $rows->execute($this->param);
        return $rows->fetchAll(pdo::FETCH_ASSOC); 
    }
    
     public function fetchNUM()
    {
        $rows = $this->conn->prepare($this->query.$this->groupby.$this->order.$this->limit);
        $rows->execute($this->param);
        return $rows->fetchAll(pdo::FETCH_NUM);   
    }
    
    public function fetchOBJ()
    {
        $rows = $this->conn->prepare($this->query.$this->groupby.$this->order.$this->limit);
        $rows->execute($this->param);
        return $rows->fetchAll(pdo::FETCH_OBJ);   
    }
    
    public function fetcFUNC($funcname)
    {
        $rows = $this->conn->prepare($this->query.$this->groupby.$this->order.$this->limit);
        $rows->execute($this->param);
        return $rows->fetchAll(pdo::FETCH_FUNC, $funcname);  
    }
    
    public function fetchCOL($column=0)
    {
        $rows = $this->conn->prepare($this->query.$this->groupby.$this->order.$this->limit);
        $rows->execute($this->param); 
        return $rows->fetchAll(pdo::FETCH_COLUMN, $column);  
    }
    
    public function fetchCLASS($class)
    {
        $rows = $this->conn->prepare($this->query.$this->groupby.$this->order.$this->limit);
        $rows->execute($this->param);
        return $rows->fetchAll(pdo::FETCH_CLASS, $class);  
    }
    
    public function fetchGROUP()
    {
        $rows = $this->conn->prepare($this->query.$this->groupby.$this->order.$this->limit);
        $rows->execute($this->param);
        return $rows->fetchAll(pdo::FETCH_CLASS | pdo::FETCH_GROUP);  
    }
}
?>